package net.oschina.simpleplus.shiro;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {
	private static final long ExpireTime = TimeUnit.HOURS.toMillis(6);
	
	private Cache<Object, CacheObject> counts;
	public RetryLimitHashedCredentialsMatcher(String hashAlgorithmName, CacheManager cacheManager) {
		super(hashAlgorithmName);
		
		counts = cacheManager.getCache("counts");
	}

	@Override
	public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
		CacheObject count = counts.get(token.getPrincipal());
		if(count == null){
			counts.put(token.getPrincipal(), count = new CacheObject());
		}
		if(count.isExpire()){
			counts.put(token.getPrincipal(), count = new CacheObject());
		}
		boolean doCredentialsMatch = super.doCredentialsMatch(token, info);
		if(doCredentialsMatch){
			counts.remove(token.getPrincipal());
			return doCredentialsMatch;
		}
		if(count.incrementAndGet() >= 5){
			throw new RuntimeException("");
		}
		
		return doCredentialsMatch;
	}
	
	private class CacheObject{

		private AtomicInteger count;
		private long createTimeInMills;
		
		private CacheObject() {
			this.count = new AtomicInteger(0);
			this.createTimeInMills = System.currentTimeMillis();
		}
		
		public int incrementAndGet() {
			return count.incrementAndGet();
		}

		private boolean isExpire(){
			return System.currentTimeMillis() < createTimeInMills + ExpireTime;
		}
	}
	
}
